package com.lzj.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lzj.admin.mapper.CustomerReturnListMapper;
import com.lzj.admin.mapper.SaleListMapper;
import com.lzj.admin.pojo.*;
import com.lzj.admin.mapper.CustomerMapper;
import com.lzj.admin.query.CustomerQuery;
import com.lzj.admin.service.IAreaService;
import com.lzj.admin.service.ICustomerService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzj.admin.utils.AssertUtil;
import com.lzj.admin.utils.PageResultUtil;
import com.lzj.admin.utils.PinYinUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 客户表 服务实现类
 * </p>
 *
 * @author luoyoumou
 * @date 2022-12-08
 */
@Service
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements ICustomerService {

    @Resource
    private IAreaService areaService;

    @Resource
    private SaleListMapper saleListMapper;

    @Resource
    private CustomerReturnListMapper customerReturnListMapper;

    /**
     * 查询客户列表
     * @param customerQuery
     * @return
     */
    @Override
    public Map<String, Object> customerList(CustomerQuery customerQuery) {
        IPage<Customer> page = new Page<Customer>(customerQuery.getPage(),customerQuery.getLimit());
        page = this.baseMapper.queryCustomerByParams(page,customerQuery);
        return PageResultUtil.getResult(page.getTotal(),page.getRecords());
    }

    @Override
    public Customer findCustomerByNameNumberAddress(String name, String number, String address) {
        return this.getOne(new QueryWrapper<Customer>()
                .eq("is_del",0)
                .eq("name",StringUtils.isNotBlank(name)?name:"未知")
                .eq("number",StringUtils.isNotBlank(number)?number:"未知")
                .eq("address",StringUtils.isNotBlank(address)?number:"未知"));
    }

    /**
     * 查看是否存在 指定的联系电话 的客户
     * @param number
     * @return
     */
    public Customer findCustomerByNumber(String number){
        return this.getOne(new QueryWrapper<Customer>().eq("is_del",0).like("number",number));
    }

    /**
     * 查看是否存在 指定的联系电话 的客户 排除指定的客户Id
     * @param number
     * @param id
     * @return
     */
    public Customer findCustomerByNumber(String number,Integer id){
        return this.getOne(new QueryWrapper<Customer>().eq("is_del",0).notIn("id",id).like("number",number));
    }

    /**
     * 添加客户
     * 客户 名称 联系电话 地址 三者 至少有一个选项非空
     * 客户 名称 联系电话 地址 如果为空：置为 "未知"
     * 客户 名称 联系电话 地址 唯一定位一条记录
     * 客户 联系电话合法性检查：判断 联系电话 是否已属于指定注册用户
     * 小区全名 非空 且存在 StringUtils.isNotBlank(str)
     * 后期需要进一步考虑 areaId ?
     * isDel 0
     * @param customer
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void saveCustomer(Customer customer) {
        checkParams(customer.getName(),customer.getNumber(),customer.getAddress());
        AssertUtil.isTrue(null != this.findCustomerByNameNumberAddress(customer.getName().trim(),customer.getNumber().trim(),customer.getAddress().trim()),"客户已存在！");

        // 判断 联系电话 是否已属于指定注册用户
        if( customer.getNumber().trim().length() > 0 ){
            String tempNumbers = customer.getNumber().replaceAll("[^0-9\\-]+"," ").trim();
            for (String s : tempNumbers.split(" ")){
                AssertUtil.isTrue(null != findCustomerByNumber(s),"联系电话已被其他客户占用，请检查！");
            }
            customer.setNumber(customer.getNumber().replaceAll("\\W+", " ").trim());
        }
        customer.setIsDel(0);
        customer.setIsBlack("否");
        if(null == customer.getName() || customer.getName().trim().length() == 0) {
            customer.setName("未知");
        }
        if(null == customer.getNumber() || customer.getNumber().trim().length() == 0) {
            customer.setNumber("未知");
        }
        if(null == customer.getAddress() || customer.getAddress().trim().length() == 0) {
            customer.setAddress("未知");
        }
        customer.setName(customer.getName().trim());
        customer.setNumber(customer.getNumber().trim());
        customer.setAddress(customer.getAddress().trim());
        customer.setFpyName(PinYinUtil.getFirstSpell(customer.getName()));
//        Date cdate = new Date();
//        customer.setRegisterDate(cdate);
        // customer.setLastTradeDate(cdate);
        AssertUtil.isTrue(!(this.save(customer)),"记录添加失败！");
    }

    /**
     * 修改客户
     * @param customer
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void updateCustomer(Customer customer) {
        AssertUtil.isTrue(null == this.getById(customer.getId()),"请选择客户记录！");
        checkParams(customer.getName(),customer.getNumber(),customer.getAddress());
        Customer tempCustomer = this.findCustomerByNameNumberAddress(customer.getName().trim(),customer.getNumber().trim(),customer.getAddress().trim());
        AssertUtil.isTrue(null != tempCustomer && !(tempCustomer.getId().equals(customer.getId())),"客户已存在！");

        // 判断 联系电话 是否已属于指定注册用户
        if( customer.getNumber().trim().length() > 0 ){
            String tempNumbers = customer.getNumber().replaceAll("[^0-9\\-]+"," ").trim();
            for (String s : tempNumbers.split(" ")){
                AssertUtil.isTrue(null != findCustomerByNumber(s,customer.getId()),"联系电话已被其他客户占用，请检查！");
            }
            customer.setNumber(customer.getNumber().replaceAll("\\W+", " ").trim());
        }
        customer.setFpyName(PinYinUtil.getFirstSpell(customer.getName()));
        if(null == customer.getName() || customer.getName().trim().length() == 0) {
            customer.setName("未知");
        }
        if(null == customer.getNumber() || customer.getNumber().trim().length() == 0) {
            customer.setNumber("未知");
        }
        if(null == customer.getAddress() || customer.getAddress().trim().length() == 0) {
            customer.setAddress("未知");
        }
        customer.setName(customer.getName().trim());
        customer.setNumber(customer.getNumber().trim());
        customer.setAddress(customer.getAddress().trim());
        AssertUtil.isTrue(!(this.updateById(customer)),"记录更新失败！");
    }

    /**
     * 删除客户
     *   已经产生单据的客户不能删除
     * @param ids
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void deleteCustomer(Integer[] ids) {
        AssertUtil.isTrue(null == ids || ids.length == 0,"请选择待删除的记录id！");

        QueryWrapper<SaleList> saleListQueryWrapper = new QueryWrapper<SaleList>().in("customer_id",ids).last("limit 1");
        List<SaleList> tSaleList = saleListMapper.selectList(saleListQueryWrapper);
        AssertUtil.isTrue(!(tSaleList.isEmpty()),"客户已产生单据，不能被删除！");

        QueryWrapper<CustomerReturnList> customerReturnListQueryWrapper = new QueryWrapper<CustomerReturnList>().in("customer_id",ids).last("limit 1");
        List<CustomerReturnList> tCustomerReturnList = customerReturnListMapper.selectList(customerReturnListQueryWrapper);
        AssertUtil.isTrue(!(tCustomerReturnList.isEmpty()),"客户已产生单据，不能被删除！");

        List<Customer> customerList = new ArrayList<Customer>();
        LocalDateTime dateTime = LocalDateTime.now();
        for(Integer id : ids){
            Customer tempCustomer = this.getById(id);
            tempCustomer.setIsDel(1);
            customerList.add(tempCustomer);
        }
        AssertUtil.isTrue(!(this.updateBatchById(customerList)),"记录删除失败！");
    }

    /**
     * 客户 名称 联系人 电话号码 非空的参数校验
     * @param name
     * @param number
     * @param address
     */
    private void checkParams(String name, String number, String address) {
        AssertUtil.isTrue(StringUtils.isBlank(name) && StringUtils.isBlank(number) && StringUtils.isBlank(address),"请输入客户信息！(名称、电话、地址 至少一项非空)");
    }

    /**
     * 根据客户姓名查询客户对象
     * @param name
     * @return
     */
    @Override
    public Customer findCustomerByName(String name) {
        return this.getOne(new QueryWrapper<Customer>().eq("is_del",0).eq("name",name));
    }

}
